﻿using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;

namespace Nikse.SubtitleEdit.Logic
{
    public static class TextDraw
    {

        public static void DrawText(Font font, StringFormat sf, System.Drawing.Drawing2D.GraphicsPath path, StringBuilder sb, bool isItalic, bool isBold, bool isUnderline, float left, float top, ref bool newLine, float leftMargin, ref int pathPointsStart)
        {
            var next = new PointF(left, top);

            if (path.PointCount > 0)
            {
                int k = 0;

                PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
                for (int i = list.Length -1; i >= 0; i--)
                {
                    if (list[i].X > next.X)
                        next.X = list[i].X;
                    k++;
                    if (k > 60)
                        break;
                    if (i <= pathPointsStart && pathPointsStart != -1)
                        break;
                }
            }

            if (newLine)
            {
                next.X = leftMargin;
                newLine = false;
                pathPointsStart = path.PointCount;
            }

            var fontStyle = FontStyle.Regular;
            if (isItalic && isBold && isUnderline)
                fontStyle = FontStyle.Italic | FontStyle.Bold | FontStyle.Underline;
            else if (isItalic && isBold)
                fontStyle = FontStyle.Italic | FontStyle.Bold;
            else if (isItalic && isUnderline)
                fontStyle = FontStyle.Italic | FontStyle.Underline;
            else if (isUnderline && isBold)
                fontStyle = FontStyle.Underline | FontStyle.Bold;
            else if (isItalic)
                    fontStyle = FontStyle.Italic;
            else if (isBold)
                fontStyle = FontStyle.Bold;
            else if (isUnderline)
                fontStyle = FontStyle.Underline;
            try
            {
                path.AddString(sb.ToString(), font.FontFamily, (int)fontStyle, font.Size, next, sf);
            }
            catch
            {
                fontStyle = FontStyle.Regular;
                try
                {
                    path.AddString(sb.ToString(), font.FontFamily, (int)fontStyle, font.Size, next, sf);
                }
                catch
                {
                    path.AddString(sb.ToString(), new FontFamily("Arial"), (int)fontStyle, font.Size, next, sf);
                }
            }
            sb.Length = 0;
        }

        public static float MeasureTextWidth(Font font, string text, bool bold)
        {
            var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near };
            var path = new GraphicsPath();

            var sb = new StringBuilder(text);
            bool isItalic = false;
            bool newLine = false;
            int leftMargin = 0;
            int pathPointsStart = -1;
            TextDraw.DrawText(font, sf, path, sb, isItalic, bold, false, 0, 0, ref newLine, leftMargin, ref pathPointsStart);

            float width = 0;
            PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
            int index = list.Length - 42;
            if (index < 0)
                index = 0;
            for (int i = index; i < list.Length; i+=2)
            {
                if (list[i].X > width)
                    width = list[i].X;
            }
            int max = 52;
            if (max > list.Length)
                max = list.Length;
            for (int i = 0; i < max; i+=2)
            {
                if (list[i].X > width)
                    width = list[i].X;
            }

            return width;
        }

        public static float MeasureTextHeight(Font font, string text, bool bold)
        {
            var sf = new StringFormat { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Near };
            var path = new GraphicsPath();

            var sb = new StringBuilder(text);
            bool isItalic = false;
            bool newLine = false;
            int leftMargin = 0;
            int pathPointsStart = -1;
            TextDraw.DrawText(font, sf, path, sb, isItalic, bold, false, 0, 0, ref newLine, leftMargin, ref pathPointsStart);

            float height = 0;
            PointF[] list = (PointF[])path.PathPoints.Clone(); // avoid using very slow path.PathPoints indexer!!!
            int index = list.Length - 80;
            if (index < 0)
                index = 0;
            for (int i = index; i < list.Length; i+=2)
            {
                if (list[i].Y > height)
                    height = list[i].Y;
            }

            for (int i = 0; i < list.Length; i+=2)
            {
                if (list[i].Y > height)
                    height = list[i].Y;
            }

            return height;
        }


    }
}
